package com.cssp.dao.hibernate.base;

import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class HibernateBaseDao<T> extends HibernateDaoSupport {

	@SuppressWarnings("unchecked")
	private Class persistentClass;

	@SuppressWarnings("unchecked")
	public HibernateBaseDao() {
		persistentClass = (Class) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@SuppressWarnings("unchecked")
	public T findById(String id) {
		return (T) getHibernateTemplate().get(getPersistentClass(), id);
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		return getHibernateTemplate().loadAll(getPersistentClass());
	}

	@SuppressWarnings("unchecked")
	protected List<T> findByHql(final String hql, Object value){
		return this.getHibernateTemplate().find(hql, value);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> findByHql(final String hql, Object[] values){
		return this.getHibernateTemplate().find(hql, values);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> findByHql(final String hql, final Map paramMap,
			final int firstResult, final int maxResult) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setProperties(paramMap);
				query.setFirstResult(firstResult);
				query.setMaxResults(maxResult);
				return query.list();
			}

		});
	}

	@SuppressWarnings("unchecked")
	protected List<T> findByHql(String hql, String param, Object value,
			int firstResult, int maxResult) {
		Map paramMap = new HashMap();
		paramMap.put(param, value);
		return findByHql(hql, paramMap, firstResult, maxResult);
	}

	public void save(T t) {
		this.getHibernateTemplate().save(t);
	}

	public void update(T t) {
		this.getHibernateTemplate().update(t);
	}

	public void saveOrUpdate(T t) {
		this.getHibernateTemplate().saveOrUpdate(t);
	}

	public void merge(T t) {
		this.getHibernateTemplate().merge(t);
	}

	public void delete(T t) {
		this.getHibernateTemplate().delete(t);
	}

	public void deleteById(String id) {
		T t = findById(id);
		this.getHibernateTemplate().delete(t);
	}

	@SuppressWarnings("unchecked")
	public Class getPersistentClass() {
		return persistentClass;
	}
}
